package me.bincker.formwork.web.modules.system.controller

import me.bincker.formwork.web.entity.ResultPage
import me.bincker.formwork.web.test.TestSession
import me.bincker.formwork.web.modules.system.entity.Role
import me.bincker.formwork.web.test.RequestPostProcessors
import me.bincker.formwork.web.test.ResultMatchers
import me.bincker.formwork.web.test.TestUtils
import org.junit.Test
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Pageable
import org.springframework.http.MediaType
import org.springframework.test.context.junit4.SpringRunner
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.context.WebApplicationContext

@SpringBootTest
@RunWith(SpringRunner::class)
class RoleControllerTest {
    companion object{
        fun getPage(session: TestSession, pageable: Pageable, role: Role? = null): ResultPage<Role>{
            val result = session.perform(
                    session.get("/roles")
                            .with(RequestPostProcessors.setPageableParam(pageable))
                            .with(RequestPostProcessors.setQueryParam(role))
            )
                    .andExpect(ResultMatchers.IS_OK)
                    .andReturn()
            return TestUtils.deSerialiseJson(result.response.contentAsString)
        }

        fun getOne(session: TestSession, id: String) :Role{
            val result = session.perform(
                    session.get("/roles/{id}", id)
            )
                    .andExpect(ResultMatchers.IS_OK)
                    .andReturn()
            return TestUtils.deSerialiseJson(result.response.contentAsString)
        }

        fun add(session: TestSession, role: Role) :Role{
            val result = session.perform(
                    session.post("/roles")
                            .contentType(MediaType.APPLICATION_JSON_UTF8)
                            .content(TestUtils.serialiseJson(role))
            )
                    .andExpect(ResultMatchers.IS_OK)
                    .andReturn()
            return TestUtils.deSerialiseJson(result.response.contentAsString)
        }

        fun put(session: TestSession, role: Role) :Role{
            val result = session.perform(
                    session.put("/roles")
                            .contentType(MediaType.APPLICATION_JSON_UTF8)
                            .content(TestUtils.serialiseJson(role))
            )
                    .andExpect(ResultMatchers.IS_OK)
                    .andReturn()
            return TestUtils.deSerialiseJson(result.response.contentAsString)
        }
    }

    @Autowired
    private lateinit var webApplicationContext: WebApplicationContext

    @Test
    fun getPage(){
        val session = TestSession(webApplicationContext)
        session.login()
        println(getPage(session, PageRequest.of(0, 20)))
    }

    @Test
    fun getOne(){
        val session = TestSession(webApplicationContext)
        session.login()
        println(getOne(session, "1"))
    }

    @Test
    @Transactional
    fun add(){
        val session = TestSession(webApplicationContext)
        session.login()
        val permissionList = PermissionControllerTest.getAll(session)
        val role = Role()
        role.permissions = permissionList.map { permission-> permission.code }.toMutableSet()
        role.code = "ROLE_TEST"
        println(add(session, role))
    }

    @Test
    @Transactional
    fun put(){
        val session = TestSession(webApplicationContext)
        session.login()
        val permissionList = PermissionControllerTest.getAll(session)
        val role = getOne(session, "1")
        role.permissions = permissionList.map { permission->permission.code }.toMutableSet()
        println(put(session, role))
    }
}
